package luke.core.controller;

import luke.audio.metadata.Song;
import luke.audio.metadata.SongMetadataExtractor;
import luke.core.utils.AppStateManager;
import luke.core.utils.PlaybackStateManager;
import luke.media.audio.AdvancedAudioPlayer;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 播放控制器类
 * 作为播放控制的唯一入口，负责协调PlaybackStateManager、AdvancedAudioPlayer和各UI组件
 */
public class PlayController {
    private PlaybackStateManager playbackStateManager;
    private AdvancedAudioPlayer advancedAudioPlayer;

    private static PlayController playController;
    private File inputCurrentFile;

    private List<File> sharedSelectedFiles;


    public void setSharedSelectedFiles() {
        AppStateManager appStateManager = AppStateManager.getInstance();
        this.sharedSelectedFiles = appStateManager.getSharedSelectedFiles();
    }


    public void setInputCurrentFile(File inputCurrentFile) {
        this.inputCurrentFile = inputCurrentFile;
    }

    public static PlayController getInstance() {
        if (playController == null) {
            playController = new PlayController();
        }
        return playController;
    }

    public static class BeatsData {
        public Double bpm;
        public int offset;

        public BeatsData(double bpm, int offset) {
            this.bpm = bpm;
            this.offset = offset;
        }

        public BeatsData() {

        }

    }


    private SongMetadataExtractor songMetadataExtractor;

    public PlayController() {
        // 获取PlaybackStateManager单例实例
        this.playbackStateManager = PlaybackStateManager.getInstance();
        // 初始化高级音频播放器
        this.advancedAudioPlayer = new AdvancedAudioPlayer();
        songMetadataExtractor = SongMetadataExtractor.getInstance();

    }

    /**
     * 切换播放状态（播放/暂停）
     */
    public void togglePlayback() {
        // 检查是否有文件加载
        if (inputCurrentFile == null) {
            return;
        }
        advancedAudioPlayer.togglePlayback(inputCurrentFile);
    }

    /**
     * 跳转到指定时间位置
     *
     * @param position 位置（0到1之间的小数）
     */
    public void seekTo(double position) {
        // 计算时间位置（毫秒）
        long positionMs = (long) (position * playbackStateManager.getTotalDurationMs());
        System.out.println("拖动到的位置是:" + positionMs);
        advancedAudioPlayer.seekTo(positionMs);
    }

    /**
     * 播放下一曲
     */
    public void playNextTrack() {
        if (sharedSelectedFiles.isEmpty()) {
            return; // 播放列表为空时直接返回
        }

        // 获取当前播放的文件
        if (inputCurrentFile == null) {
            return; // 当前没有播放文件时直接返回
        }

        // 转换为 List 以便按顺序遍历
        List<File> fileList = new ArrayList<>(sharedSelectedFiles);

        // 查找当前文件在列表中的索引
        int currentIndex = fileList.indexOf(inputCurrentFile);
        if (currentIndex == -1) {
            return; // 当前文件不在播放列表中
        }

        // 计算下一曲的索引
        int nextIndex = (currentIndex + 1) % fileList.size();
        File nextFile = fileList.get(nextIndex);
        inputCurrentFile = nextFile;

        // 播放下一曲
        advancedAudioPlayer.togglePlayback(inputCurrentFile);
    }


    /**
     * 播放上一曲
     */
    public void playPreviousTrack() {
        if (sharedSelectedFiles.isEmpty()) {
            return; // 播放列表为空时直接返回
        }

        // 获取当前播放的文件

        if (inputCurrentFile == null) {
            return; // 当前没有播放文件时直接返回
        }

        // 转换为 List 以便按顺序遍历
        List<File> fileList = new ArrayList<>(sharedSelectedFiles);

        // 查找当前文件在列表中的索引
        int currentIndex = fileList.indexOf(inputCurrentFile);
        if (currentIndex == -1) {
            return; // 当前文件不在播放列表中
        }

        // 计算上一曲的索引
        int previousIndex = (currentIndex - 1 + fileList.size()) % fileList.size();
        File previousFile = fileList.get(previousIndex);
        inputCurrentFile = previousFile;

        // 播放上一曲
        advancedAudioPlayer.togglePlayback(inputCurrentFile);
    }


    /**
     * 更新鼓点
     *
     * @param beatsData 鼓点数据
     */
    public void updateBeatsData(BeatsData beatsData) {
        advancedAudioPlayer.updateBeat(beatsData);
    }

    /**
     * 恢复保存的鼓点
     *
     * @return 鼓点数据
     */
    public void restoreBeats() {
        // 这里实现恢复鼓点的逻辑
        try {
            Song song = songMetadataExtractor.extractMetadataDirectly(playbackStateManager.getCurrentFile());
            updateBeatsData(new PlayController.BeatsData(song.getBpm(), song.getBeatOffset()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 切换鼓点启用状态
     */
    public void toggleBeatEnabled() {
        boolean currentBeatEnabled = playbackStateManager.isBeatEnabled();
        boolean newBeatEnabled = !currentBeatEnabled;
        System.out.println("收到切换为鼓点状态到:" + newBeatEnabled);
        advancedAudioPlayer.toggleBeatEnabled(newBeatEnabled);
    }

    /**
     * 保存当前播放的鼓点
     */
    public void saveBeats(BeatsData beatsData) {
        advancedAudioPlayer.saveBeatsData(beatsData);
        // 显示波形图中的鼓点线条（当保存鼓点时）
        showBeatLines();
    }


    /**
     * 音量设置
     */
    public void setMasterVolume(float volume) {
        advancedAudioPlayer.setMasterVolume(volume);
    }

    /**
     * 更新鼓点声音大小
     */
    public void setBeatVolume(float volume) {
        // 直接将节拍音量传递给AdvancedAudioPlayer，不再放大
        advancedAudioPlayer.updateBeatVolume(volume);
    }

    /**
     * 更新鼓点声音类型
     */
    public void setBeatSoundType(int soundType) {
        advancedAudioPlayer.updateBeatSoundType(soundType);
    }

    /**
     * 更新背景音量
     */
    public void setBackgroundVolume(float volume) {
        advancedAudioPlayer.updateBackgroundVolume(volume);
    }

    /**
     * 获取鼓点位置列表
     *
     * @param audioDurationMs 音频总时长（毫秒）
     * @return 鼓点位置列表
     */
    public List<Integer> getBeatPositions(int audioDurationMs) {
        return advancedAudioPlayer.getBeatPositions(audioDurationMs);
    }

    /**
     * 隐藏波形图中的鼓点线条
     * 当用户第一次手敲鼓点时调用此方法
     */
    public void hideBeatLines() {
        // 通知PlaybackStateManager隐藏鼓点线条
        playbackStateManager.setBeatLinesVisible(false);
    }

    /**
     * 显示波形图中的鼓点线条
     * 当点击更新鼓点或清除鼓点时调用此方法
     */
    public void showBeatLines() {
        // 通知PlaybackStateManager显示鼓点线条
        playbackStateManager.setBeatLinesVisible(true);
    }
}